import socket from '../../../utils/socket.js';
import setting from './setting.vue';
export default {
    name: 'webRtc',
    components: {
      setting
    },
    data() {
        return {
            account: window.sessionStorage.account || '',
            isJoin: false,
            userList: [],
            roomid: 'webrtc_1v1', // 指定房间ID
            isCall: false, // 正在通话的对象
            loading: false,
            loadingText: '呼叫中',
            isToPeer: false, // 是否建立了 P2P 连接
            peer: null,
            offerOption: {
                offerToReceiveAudio: 1,
                offerToReceiveVideo: 1
            },
            //下面是我新加的
            isMedia: false, // 是否建立了 P2P 连接
            longstream: null,
            user: {},
            search: '',
            text: '',
            target: null, //聊天目标
            pageChat: [], //聊天框
            videobig:'rtcA',//rtcB
            DisplayLocalstream:null,
            UserLocalstream:null,
            chatType:'round',
            mediaType:'getUserMedia',// getDisplayMedia | getUserMedia
            dialogVisible:false,
            isShowTextarea:false,
        };
    },
    methods: {
        setChatType(type){
            this.chatType=type
        },
        setMedia(){
            this.dialogVisible = false
            if(this.mediaType=='getUserMedia'){
                this.getUserMedia()
            }else{
                this.getDisplayMedia()
            }
        },
        // 分享屏幕
        async getDisplayMedia(){
            const gdmOptions = {
              video: {
                cursor: "always"
              },
              audio:false,
              /*              audio: {
                echoCancellation: true,
                noiseSuppression: true,
                sampleRate: 44100
              }*/
            }
            // this.stopStream()
            // 保存本地流到全局
            try {
                this.DisplayLocalstream = await navigator.mediaDevices.getDisplayMedia({audio: true,video: {mediaSource: 'screen'}});
                let video = document.querySelector('#rtcA');
                if(video.srcObject){
                   video.srcObject.getTracks().forEach(track => {
                       track.stop();
                   }); 
                }
                video.srcObject = this.DisplayLocalstream;
                this.isMedia=true
                // console.log('this.DisplayLocalstream.getVideoTracks():',this.DisplayLocalstream.getVideoTracks())
                // console.log('this.DisplayLocalstream.getAudioTracks():',this.DisplayLocalstream.getAudioTracks())
                console.log('this.DisplayLocalstream.getTracks():',this.DisplayLocalstream.getTracks())
                this.localstream=this.DisplayLocalstream;
            } catch (e) {
                console.log('getDisplayMedia: ', e)
            }
        },
        // 分享摄像头和麦克风
        async getUserMedia(){
            // this.stopStream()
            // 保存本地流到全局
            try {
                this.UserLocalstream = await navigator.mediaDevices.getUserMedia({
                    audio: {
                        echoCancellation:true,//是否使用回声消除来尝试去除通过麦克风回传到扬声器的音频
                        channelCount:2,//单声道的时候为1，立体声的时候为2
                        noiseSuppression:true,//是否尝试去除音频信号中的背景噪声
                    },
                    video: {
                        aspectRatio: {
                            ideal: 1.777777 // 16:9比例优先
                        },
         /*               mandatory: {
                                maxHeight: 180,
                                maxWidth: 320
                            }*/
                    }
                });
                let video = document.querySelector('#rtcA');
                if(video.srcObject){
                   video.srcObject.getTracks().forEach(track => {
                       track.stop();
                   }); 
                }
                video.srcObject = this.UserLocalstream;
                this.isMedia=true
                // console.log('this.UserLocalstream.getVideoTracks():',this.UserLocalstream.getVideoTracks())
                // console.log('this.UserLocalstream.getAudioTracks():',this.UserLocalstream.getAudioTracks())
                // console.log('this.UserLocalstream.getTracks():',this.UserLocalstream.getTracks())
                this.localstream=this.UserLocalstream;
            } catch (e) {
                console.log('getUserMedia: ', e)
            }
        },

        stopStream(){
            if(this.localstream){
                this.localstream.getTracks().forEach(track => {
                    track.stop();
                });
                this.localstream=null
            }
        },
        // 登录相关开始
        /*
           房间ID roomid 为 活动 activityId 
           登录名 account 为 userId
           window.sessionStorage 用于临时保存同一窗口(或标签页)的数据，刷新还在保存 在关闭窗口或标签页之后将会删除这些数据。
        */
        join() {
            if (!this.account) return;
            this.isJoin = true;
            window.sessionStorage.account = this.account;
            socket.emit('join', { roomid: this.roomid, account: this.account , isUserMedia:this.isUserMedia});
        },
        // 登录相关结束
        onMessage(data){
            console.log('onMessage',data)
            if(data.type=='text'){
                this.acceptText(data)
            }else{
                console.log(data)
            }
        },
        // 文字聊天开始
        // 接收
        acceptText(data) {
            this.pageChat.push(data)
        },
        showFile(){
            var file = document.querySelector('input[type="file"]')
              .files[0];
              console.log(file)
        },
        binary(){
            // socket.binary(false).emit('an event', { some: 'data' });// 发送二进制 数据  指定发出的数据是否包含二进制。指定时提高性能。可以是true或false。
            var file = document.querySelector('input[type="file"]')
              .files[0];
              console.log(file)
            let data = { roomid: this.roomid, 
                self: this.account, 
                type: 'Blob', 
                data: file,
                fileName: file.name,
                fileSize: file.size,
                fileType: file.type,
                 date: new Date().toLocaleString() 
             }
            socket.emit('offer', data)

        },
        // 发送
        sendText() {
            if (!this.text) return
            let data = { roomid: this.roomid, self: this.account, type: 'text', text: this.text, date: new Date().toLocaleString() }
            socket.emit('offer', data)

            this.pageChat.push(data)
            this.text = ''
        },
        // 文字聊天结束

        // 纯语音聊天开始
        // 纯语音聊天结束

        // 视频语音聊天开始
        myapply() {
            if (!this.target) return
            this.apply(this.target.account)
        },
        // 视频语音聊天结束

        // socket 连接相关 开始
        // socket 连接相关 结束

        // RTCPeerConnection 相关开始
        // RTCPeerConnection 相关结束

        // video 流相关 开始
        // video 流相关 结束

        initSocket() {
            socket.on('joined', (data) => { // 收到登录
                this.userList = data;
                console.log(data)
            });
            socket.on('reply', async data => { // 收到回复
                this.loading = false;
                console.log(data);
                switch (data.type) {
                    case '1': // 同意
                        this.isCall = data.self;
                        // 对方同意之后创建自己的 peer
                        await this.createP2P(data);
                        // 并给对方发送 offer
                        this.createOffer(data);
                        break;
                    case '2': //拒绝
                        this.$message({
                            message: '对方拒绝了你的请求！',
                            type: 'warning'
                        });
                        break;
                    case '3': // 正在通话中
                        this.$message({
                            message: '对方正在通话中！',
                            type: 'warning'
                        });
                        break;
                    case '4': // 发送文字
                        this.acceptText(data)
                        break;
                    default:
                        console.error('收到没有匹配的回复！')
                }
            });
            socket.on('apply', data => { // 收到请求
                if (this.isCall) {
                    this.reply(data.self, '3');
                    return;
                }
                this.$confirm(data.self + ' 向你请求视频通话, 是否同意?', '提示', {
                    confirmButtonText: '同意',
                    cancelButtonText: '拒绝',
                    type: 'warning'
                }).then(async () => {
                    await this.createP2P(data); // 同意之后创建自己的 peer 等待对方的 offer
                    this.isCall = data.self;
                    this.reply(data.self, '1');
                }).catch(() => {
                    this.reply(data.self, '2');
                });
            });
            socket.on('1v1answer', (data) => { // 接收到 answer
                this.onAnswer(data);
            });
            socket.on('1v1ICE', (data) => { // 接收到 ICE
                this.onIce(data);
            });
            socket.on('1v1offer', (data) => { // 接收到 offer
                this.onOffer(data);
            });
            socket.on('1v1hangup', _ => { // 通话挂断
                this.$message({
                    message: '对方已断开连接！',
                    type: 'warning'
                });
                this.peer.close();
                this.peer = null;
                this.isToPeer = false;
                this.isCall = false;
                this.localstream.getTracks().forEach(track => {
                    track.stop();
                });
            });
            socket.on('offer', (data) => { // 接收到 message
                console.log('socket.on',data)
                this.onMessage(data);
            });
        },
        hangup() { // 挂断通话
            socket.emit('1v1hangup', { account: this.isCall, self: this.account });
            this.peer.close();
            this.peer = null;
            this.isToPeer = false;
            this.isCall = false;
            this.localstream.getTracks().forEach(track => {
                track.stop();
            });
        },
        apply(account) {
            // account 对方account  self 是自己的account
            this.loading = true;
            this.loadingText = '呼叫中';
            socket.emit('apply', { account: account, self: this.account });
        },
        reply(account, type) {
            socket.emit('reply', { account: account, self: this.account, type: type });
        },
        async createP2P(data) {
            // this.loading = true;
            // this.loadingText = '正在建立通话连接';
            await this.createMedia(data);
        },
        async createMedia(data) {
            const constraints = {
              width: {min: 640, ideal: 1280},
              height: {min: 480, ideal: 720},
              advanced: [
                {width: 1920, height: 1280},
                {aspectRatio: 1.333}
              ]
            };
            // 保存本地流到全局
            if(!this.localstream){
                try {
                    this.localstream = await navigator.mediaDevices.getUserMedia(constraints);
                    // this.localstream = await navigator.mediaDevices.getDisplayMedia({video: {mediaSource: 'screen'}});
                    // const trackgetVideoTracks = this.localstream.getVideoTracks()[0];
                    // const trackgetAudioTracks = this.localstream.getAudioTracks() ;// 获取 Audio 流 数组
                    // const trackgetTracks = this.localstream.getTracks() ;// 获取 所有 流 数组
                    // track.applyConstraints(constraints) // 添中约束
                    let video = document.querySelector('#rtcA');
                    video.srcObject = this.localstream;
                } catch (e) {
                    console.log('getUserMedia: ', e)
                }

            }           
            this.initPeer(data); // 获取到媒体流后，调用函数初始化 RTCPeerConnection
        },
        initPeer(data) {
            // 创建输出端 PeerConnection
            let PeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
            this.peer = new PeerConnection();            
            this.peer.addStream(this.localstream); // 添加本地流
            // 监听ICE候选信息 如果收集到，就发送给对方
            this.peer.onicecandidate = (event) => {
                if (event.candidate) {
                    socket.emit('1v1ICE', { account: data.self, self: this.account, sdp: event.candidate });
                }
            };
            this.peer.onaddstream = (event) => { // 监听是否有媒体流接入，如果有就赋值给 rtcB 的 src
                this.isToPeer = true;
                this.loading = false;
                let video = document.querySelector('#rtcB');
                video.srcObject = event.stream;
            };
            this.peer.oniceconnectionstatechange = (event)=> { //。当连接的ICE代理的状态（以该iceConnectionState属性表示）改变时，会触发。
/*              if (this.peer.iceConnectionState === "failed" ||
                  this.peer.iceConnectionState === "disconnected" ||
                  this.peer.iceConnectionState === "closed") {
                // Handle the failure
              }*/
              // console.log(event)
            };
            this.peer.onicegatheringstatechange = ev => {//当ICE候选者收集过程的状态发生变化时
              let connection = ev.target;
              console.log(connection)

              // switch(connection.iceGatheringState) {
              //   case "gathering":
              //     /* collection of candidates has begun */
              //     break;
              //   case "complete":
              //     /* collection of candidates is finished */
              //     break;
              // }
            }
            this.peer.onopen = ev => {
                console.log('this.peer.onopen 打开')
            }
        },
        async createOffer(data) { // 创建并发送 offer
            try {
                // 创建offer
                let offer = await this.peer.createOffer(this.offerOption);
                // 呼叫端设置本地 offer 描述
                await this.peer.setLocalDescription(offer);
                // 给对方发送 offer
                socket.emit('1v1offer', { account: data.self, self: this.account, sdp: offer });
            } catch (e) {
                console.log('createOffer: ', e);
            }
        },
        async onOffer(data) { // 接收offer并发送 answer
            try {
                // 接收端设置远程 offer 描述
                await this.peer.setRemoteDescription(data.sdp);
                // 接收端创建 answer
                let answer = await this.peer.createAnswer();
                // 接收端设置本地 answer 描述
                await this.peer.setLocalDescription(answer);
                // 给对方发送 answer
                socket.emit('1v1answer', { account: data.self, self: this.account, sdp: answer });
            } catch (e) {
                console.log('onOffer: ', e);
            }
        },
        async onAnswer(data) { // 接收answer
            try {
                await this.peer.setRemoteDescription(data.sdp); // 呼叫端设置远程 answer 描述
            } catch (e) {
                console.log('onAnswer: ', e);
            }
        },
        async onIce(data) { // 接收 ICE 候选
            try {
                await this.peer.addIceCandidate(data.sdp); // 设置远程 ICE
            } catch (e) {
                console.log('onAnswer: ', e);
            }
        },

        dragEagle(e){
            var targetDiv= document.getElementById('eagleMapContainer'); //e.target.parentNode.parentNode;.children[0]

            //得到点击时该地图容器的宽高：
            var targetDivWidth=targetDiv.offsetWidth;
            var targetDivHeight=targetDiv.offsetHeight;

            var startX=e.clientX;
            var startY=e.clientY;

            var _this=this;

            document.onmousemove=function(e){
                console.log('move');
                e.preventDefault();
                //得到鼠标拖动的宽高距离：取绝对值
                var distX=Math.abs(e.clientX-startX);
                var distY=Math.abs(e.clientY-startY);                  

                //往右上方拖动：
                if(e.clientX > startX ){
                    targetDiv.style.width=targetDivWidth+distX+'px';
                    // targetDiv.style.height=targetDivHeight+distY+'px';
                }
                //往左下方拖动：
                if (e.clientX < startX ) {
                    targetDiv.style.width=(targetDivWidth-distX)+'px';
                    // targetDiv.style.height=(targetDivHeight-distY)+'px';
                }

                //设置最大最小范围：不能无限制缩放，影响体验
                if(parseInt(targetDiv.style.width)>=1300){
                    targetDiv.style.width=1300+'px';
                }
                if(parseInt(targetDiv.style.width)<=150){
                    targetDiv.style.width=150+'px';
                }

/*                if(parseInt(targetDiv.style.height)>=300){
                    targetDiv.style.height=300+'px';
                }
                if(parseInt(targetDiv.style.height)<=150){
                    targetDiv.style.height=150+'px';
                }*/
            }

            document.onmouseup=function(){
                document.onmousemove=null;
            }
        },
        info(){
            this.$message({
                message: '开发中！',
                type: 'warning'
            });
        },
        init(){
            if ('getUserMedia' in navigator.mediaDevices) {
                // 请用摄像头                
              this.getUserMedia()
            }else
            if ('getDisplayMedia' in navigator.mediaDevices) {
              // use it.
              console.log("支持 getDisplayMedia()");
            } else {
              console.log("不支持 getDisplayMedia()");
              // fall back to extension way
            }
        },
        
    },
    mounted() {
        this.isUserMedia=location.origin.includes('https://')||location.origin.includes('http://localhost')
        // this.init()
        this.initSocket();
        if (this.account) {
            this.join();
            console.log('登录....')
        }
    }
}


